home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 425_01 / lzpipe / zippipe.c < prev   
Encoding:
C/C++ Source or Header  |  1994-03-13  |  7.8 KB  |  272 lines

  1. #include <stdio.h>
  2. #include "modern.h"
  3. #include "lzpipe.h"
  4. #include "zalloc.h"
  5. #include "oscode.h"
  6. #include "crc32.h"
  7. #define __ALLOCEXT__
  8. #include "zipguts.h"
  9. #ifndef UNIX
  10. #    ifdef M_XENIX
  11. #        define UNIX
  12. #    endif
  13. #    ifdef unix
  14. #        define UNIX
  15. #    endif
  16. #endif
  17. #ifdef UNIX
  18. #    include <time.h>
  19. #endif
  20. #ifdef MSDOS
  21. #    include <dos.h>
  22. #endif
  23.  
  24. #ifdef __TURBOC__
  25.     #pragma warn -rvl
  26. #endif
  27. static unsigned long dostime __ARGS__((void))
  28. {
  29. #ifdef MSDOS
  30. # ifdef __TURBOC__
  31.                 /* inline assembly ha-ha! */
  32.   __emit__(/* all arguments must be words to avoid confusion */
  33.    0x2AB4,      /* mov ah,2Ah - get date */
  34.    0x21CD,      /* int 21h   */
  35.    0xE981,1980, /* sub cx,1980 */
  36.    0xCF88,      /* mov bh,cl */
  37.    0xE7D0,      /* shl bh,1  - pack the year in BX */
  38.    0xD388,      /* mov bl,dl - pack the day  in BX */
  39.    0xD230,      /* xor dl,dl */
  40.    0x03B1,      /* mov cl,03 */
  41.    0xEAD3,      /* shr dx,cl */
  42.    0xD309,      /* or  bx,dx - pack the month -//- */
  43.  
  44.    0x2CB4,      /* mov ah,2Ch get time */
  45.    0x21CD,      /* int 21h   */
  46.    0xC031,      /* xor ax,ax */
  47.    0xCC88,      /* mov ah,cl */
  48.    0x03B1,      /* mov cl,3  */
  49.    0xE8D3,      /* shr ax,cl - pack the minutes in AX */
  50.    0xE5D2,      /* shl ch,cl */
  51.    0xEC08,      /* or  ah,ch - pack the  hours  in AX */
  52.    0xEED0,      /* shr dh,1  */
  53.    0xF008,      /* or  al,dh - pack the seconds in AX */
  54.  
  55.    0xDA89);     /* mov dx,bx - return value in DX:AX */
  56. # else
  57.    uninon REGS r;
  58.    unsigned d;
  59.  
  60.    r.h.ah = 0x2A; /* get date */
  61.    intdos(&r,&r);
  62.    d = ((r.x.cx - 1980) << 9) | (r.h.dh << 5) | r.h.dl;
  63.  
  64.    r.h.ah = 0x2C; /* get time */
  65.    intdos(&r,&r);
  66.    return ((unsigned long)d << 16) |
  67.       (r.h.ch << 11) | (r.h.cl << 5) | (r.h.dh >> 1);
  68. # endif
  69. #else
  70. # ifdef UNIX
  71.    extern long time();
  72.    struct tm *s;
  73.    long t;
  74.  
  75.    (void)time(&t);
  76.    s = gmtime(&t);
  77.    if (s->tm_year < 80) return 0L;
  78.    return ((unsigned long)(s->tm_year - 80) << 25) |
  79.       ((unsigned long)s->tm_mon << 21) | ((unsigned long)s->tm_mday << 16) |
  80.       ((unsigned)s->tm_hour << 11) | (s->tm_min << 5) | (s->tm_sec >> 1);
  81. # else
  82.    /* dummy time stamp */ return 0L;
  83. # endif
  84. #endif
  85. }
  86. #ifdef __TURBOC__
  87.     #pragma warn .rvl
  88. #endif
  89.  
  90. #ifndef zalloc
  91. /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
  92.  * and farmalloc(64K) returns a pointer with nonzero offset, so we
  93.  * must fix the pointer. Warning: the pointer must be saved in its
  94.  * original form in order to free it, use farfree().
  95.  * For MSC, use halloc instead of this function.
  96.  */
  97. void far *zalloc(void far **p, unsigned n, unsigned s)
  98. {
  99.    register unsigned long l;
  100.    l = (unsigned long)(*p = farmalloc((unsigned long)n*s + 15));
  101.    return (void far *)
  102.       ((0xffff0000L & l) + (0xffff0000L & (((0xffffL & l) + 15) << 12)));
  103. }
  104. #endif
  105.  
  106. int zipalloc()
  107. {
  108. #ifdef DYN_ALLOC
  109.    if (ct_alloc() != 0) return ZNOMEM;
  110.    if (lm_alloc() != 0) {
  111.       ct_free(); return ZNOMEM;
  112.    }
  113. #endif
  114.    return 0;
  115. }
  116.  
  117. void zipfree()
  118. {
  119. #ifdef DYN_ALLOC
  120.    lm_free();
  121.    ct_free();
  122. #endif
  123. }
  124.  
  125. #define putword(x) bi_putsh(x)
  126. static int putlong __ARGS__((ulg));
  127.  
  128. static int putlong(l)
  129. ulg l;
  130. {
  131.    return (putword((unsigned)l)!=0 ||
  132.            putword((unsigned)(l >> 16))!=0) ? ZWRITE : 0;
  133. }
  134.  
  135. static ulg inpsize;
  136. #ifdef DEBUG
  137.        ulg isize;
  138. #endif
  139. static int ziptype;
  140. static ulg timestamp;
  141. static ush flags;
  142.  
  143. /* speed options for the general purpose bit flag */
  144. #define FAST 4
  145. #define SLOW 2
  146.  
  147. int zipcreat(out_port, ztype, dlevel)
  148. #ifdef LZFILE
  149.     FILE *out_port;
  150. #else
  151.     int (*out_port)__ARGS__((int));
  152. #endif
  153. int ztype, dlevel;
  154. {
  155.    register k;
  156.  
  157.    if (dlevel<1  || dlevel>9 || (ztype!=ZIP_PKW && ztype!=ZIP_GNU))
  158.       return (lzerror = ZUNSUP);
  159.    deflate_level = dlevel;
  160.    flags = dlevel <= 1 ? FAST : dlevel >= 9 ? SLOW : 0;
  161.    ziptype = ztype;
  162.  
  163.    crcbegin();
  164.    bi_init();
  165.    if (ct_init() != 0) return (lzerror = ZNOMEM);
  166.    if ((k=lm_init()) != 0) {
  167. #ifdef DYN_ALLOC
  168.       ct_free();
  169. #endif
  170.       return (lzerror = k);
  171.    }
  172.    zip_out_port = out_port;
  173.    /* Write the header to the gzip file */
  174.    /* No extra field, file name or comment; no encryption */
  175.    if (ziptype == ZIP_GNU) {
  176.       if (putword(GZIP_MAGIC) != 0 || /* magic header */
  177.           putbyte(DEFLATED) == EOF || /* compression method */
  178.           putbyte(0) == EOF        || /* general flags: nothing */
  179.           putlong(0L) != 0         || /* dummy time stamp */
  180.           putbyte((int)flags)==EOF || /* extra flags */
  181.           putbyte(OS_CODE) == EOF)    /* OS identifier */
  182.          return (lzerror = ZWRITE);
  183.    } else {
  184.       if (putlong(PKW_MAGIC) != 0 || /* magic header */
  185.           putword(19)        != 0 || /* version to extract */
  186.           putword(flags|=8)  != 0 ||
  187.           putword(DEFLATED)  != 0 || /* compression method */
  188.       /* Who, the hell, needs in this time stamp? */
  189.           putlong(timestamp = dostime()) != 0 ||
  190.           putlong(0L) != 0 || /* dummy CRC */
  191.           putlong(0L) != 0 || /* dummy compressed size */
  192.           putlong(0L) != 0 || /* dummy original size */
  193.           putlong(0L) != 0)   /* null file name & extra fields */
  194.          return (lzerror = ZWRITE);
  195.    }
  196.    inpsize = 0L;
  197.    return 0;
  198. }
  199.  
  200. int zipwrite(buffer, length)
  201. char *buffer; unsigned length;
  202. {
  203.    register k;
  204.  
  205.    if (!zip_out_port) return (lzerror=ZNOPEN, -1);
  206.    if (length) {
  207.       updcrc((unsigned char *)buffer, length);
  208.       inpsize += length;
  209.    }
  210.    k = deflate_level > 3 ?
  211.           lazy_deflate(buffer, length) :
  212.           fast_deflate(buffer, length);
  213.    if (k == -1) lzerror = ZWRITE;
  214.    return k;
  215. }
  216.  
  217. long zipclose()
  218. {
  219.    extern unsigned minlookahead;
  220.    register long l = -1;
  221.    ulg clen, crc;
  222.  
  223.    minlookahead = 0; /* indicate end of input */
  224.    /* Flush out any remaining bytes */
  225.    if (zipwrite(NULL,0) != 0) goto end;
  226.    clen = (compressed_len >> 3);
  227.    crc = getcrc();
  228.    if (ziptype == ZIP_GNU) {
  229.       /* Write the crc. & uncompressed size */
  230.       if (putlong(crc) != 0 || putlong(inpsize) != 0) {
  231.          lzerror = ZWRITE; goto end;
  232.       }
  233.       l = 10 + clen + 8;
  234.    } else {
  235.       /* Write the data descriptor */
  236.       if (putlong(crc)        != 0 || /* CRC */
  237.           putlong(clen)       != 0 || /* compressed size */
  238.           putlong(inpsize)    != 0 || /* uncompressed size */
  239.       /* Write the central directory entry */
  240.           putlong(PKW_CENTRAL)!= 0 ||
  241.           putword((OS_CODE<<8)|20) != 0 || /* version made by */
  242.           putword(19)         != 0 || /* version to extract */
  243.           putword(flags)      != 0 ||
  244.           putword(DEFLATED)   != 0 || /* compression method */
  245.           putlong(timestamp)  != 0 ||
  246.           putlong(crc)        != 0 || /* CRC */
  247.           putlong(clen)       != 0 || /* compressed size */
  248.           putlong(inpsize)    != 0 || /* original size */
  249.           putlong(0L)         != 0 || /* filename & extra field length */
  250.           putword(0)          != 0 || /* file comment length */
  251.           putword(0)          != 0 || /* disk number start */
  252.           putword(0)          != 0 || /* internal file attributes */
  253.           putlong(0L)         != 0 || /* external file attributes */
  254.           putlong(0L)         != 0 || /* relative offset of local header */
  255.       /* Finish the central directory */
  256.           putlong(PKW_END)    != 0 ||
  257.       putlong(0L)         != 0 || /* disk numbers - don't care */
  258.       putword(1) != 0 || /* total number of CD entries on this disk */
  259.       putword(1) != 0 || /* total number of CD entries */
  260.           putlong(46L)        != 0 || /* size of the central directory */
  261.       putlong(30+clen+12) != 0 || /* offset of start of CD */
  262.           putword(0) != 0) { /* zipfile comment length */
  263.          lzerror = ZWRITE; goto end;
  264.       }
  265.       l = 30 + clen + 80;
  266.    }
  267. end:
  268.    zip_out_port = NULL;
  269.    zipfree();
  270.    return l;
  271. }
  272.